package com.fucking.great.context.common;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.fucking.great.context.GreatMain;
import com.fucking.great.context.TxnContext;
import com.gitee.sxran.dynagraphql.DynGraphqlResolverAsync;

import java.util.*;
import java.util.concurrent.*;

/**
 * 动态异步graphQHL的实现。
 * 其他的可以实现execPath
 */
public class DynGraphqlResolver extends DynGraphqlResolverAsync {

    public DynGraphqlResolver(String json) {
        this(JSONUtil.parseArray(json));
    }



    /**
     * @param json 数组
     */
    public DynGraphqlResolver(JSONArray json) {
        super(json);
    }

//    public  Object execPath(String path , JSONObject argJson, JSONObject alisJson, JSONObject subJson){
//        // 模拟交易执行时间。
//        Integer sleep = argJson.getInt("sleep",1000);
//        System.out.println(  path + "=" + System.currentTimeMillis()+"=sleep="+sleep);
//        ThreadUtil.sleep(sleep);
//        return argJson.getStr("name","lisi");
//    }


    @Override
    protected Callable<Object> newCallable(JSONObject jsonObject, ExecAction execAction, String asName) {
        return new CallableThread(this.resultJson,jsonObject,execAction,asName);
    }

    public Object execPath(String path , JSONObject argJson, JSONObject alisJson, JSONObject subJson){
        //
        TxnContext context = TxnContext.getContext();
        log.debug("context.hashCode[{}]",context.hashCode());

        // 重置参数
        context.clear();
        context.putAll(argJson);

        // 别名放到暂存里面去。
        context.putZancun("alisJson",alisJson);
        // 设置path.
        context.setPath(path);
        // 执行
//        Object result = context.forward(path);
        Object result = GreatMain.doService(context);

        // 如果sub不为空,的话就需要转化
        if(!subJson.isEmpty()){
           //
            if(result instanceof  Map){
                ((Map)result).putAll(subJson);
            }else if( result instanceof Collection){
                subJson.putOnce("data",result);
                result = subJson;
            }else if ( ClassUtil.isSimpleValueType( result.getClass() )){
                subJson.putOnce("data",result);
                result = subJson;
            }else if(ArrayUtil.isArray(result)){
                subJson.putOnce("data",new JSONArray(result));
                result = subJson;
            }else{
                // 到这里应该是普通类了。
                JSONObject jsonObject = new JSONObject(result);
                jsonObject.putAll(subJson);
            }
        }
        return result;
    }

    public class CallableThread implements Callable<Object>{
        final JSONObject resultJson;
        final JSONObject jsonObject;
        final ExecAction dynGraphqlResolver;
        final String asName;
        TxnContext context = TxnContext.getContext();
        public CallableThread(JSONObject resultJson, JSONObject jsonObject, ExecAction dynGraphqlResolver, String asName) {
            this.resultJson = resultJson;
            this.jsonObject = jsonObject;
            this.dynGraphqlResolver = dynGraphqlResolver;
            this.asName = asName;
        }

        @Override
        public Object call() throws Exception {
            TxnContext context = TxnContext.copyContext(this.context);

            Object result = dynGraphqlResolver.exec(jsonObject,asName);
            log.debug("asName[{}],context[{}],context.hashCode[{}]",asName,context,context.hashCode());
            this.resultJson.put(asName,result);
//            HadnlerInterface.ONE.endService();
            return result;
        }
    }

}
